/*============================================================================*/
/*  Copyright (C) 2009-2011,  INFRASTRUCTURE SOFTWARE CO.,LTD.
 *
 *  All rights reserved. This software is  property. Duplication
 *  or disclosure without  written authorization is prohibited.
 *
 *  @file        <>
 *  @brief       <>
 *
 *  <Compiler: CodeWarrior    MCU:XXX>
 *
 *  @author     <shushi>
 *  @date       <2018-3-20>
 */
/*============================================================================*/
/*=======[R E V I S I O N   H I S T O R Y]====================================*
*  <VERSION>    <DATE>       <AUTHOR>    <REVISION LOG>
*  V1.0.0       2018-3-20    shushi      Initial version
*  V1.0.1       2019-12-24   tao.yu      QAC check fix
*  V1.0.2       2020-1-7     tao.yu      Commercial project problem modification
============================================================================*/

/*=======[V E R S I O N  I N F O R M A T I O N]===============================*/
#define DCMDSP_C_AR_MAJOR_VERSION  4
#define DCMDSP_C_AR_MINOR_VERSION  2
#define DCMDSP_C_AR_PATCH_VERSION  2
#define DCMDSP_C_SW_MAJOR_VERSION  1
#define DCMDSP_C_SW_MINOR_VERSION  0
#define DCMDSP_C_SW_PATCH_VERSION  2

/*=======[I N C L U D E S]====================================================*/
#include "Dcm_Include.h"

/*=======[V E R S I O N  C H E C K]===========================================*/
#if (DCMDSP_C_AR_MAJOR_VERSION != DCMDSP_H_AR_MAJOR_VERSION)
  #error "DcmDsp.c : Mismatch in Specification Major Version"
#endif
#if (DCMDSP_C_AR_MINOR_VERSION != DCMDSP_H_AR_MINOR_VERSION)
  #error "DcmDsp.c : Mismatch in Specification Major Version"
#endif
#if (DCMDSP_C_AR_PATCH_VERSION != DCMDSP_H_AR_PATCH_VERSION)
  #error "DcmDsp.c : Mismatch in Specification Major Version"
#endif
#if (DCMDSP_C_SW_MAJOR_VERSION != DCMDSP_H_SW_MAJOR_VERSION)
  #error "DcmDsp.c : Mismatch in Specification Major Version"
#endif
#if (DCMDSP_C_SW_MINOR_VERSION != DCMDSP_H_SW_MINOR_VERSION)
  #error "DcmDsp.c : Mismatch in Specification Major Version"
#endif
#if (DCMDSP_C_SW_PATCH_VERSION != DCMDSP_H_SW_PATCH_VERSION)
  #error "DcmDsp.c : Mismatch in Specification Major Version"
#endif

/******************************* Define ************************************/
#if ((STD_ON == DCM_DSP_ROUTINE_FUNC_ENABLED) && (DCM_DSP_ROUTINE_MAX_NUM > 0))
	#define DCM_START_SEC_VAR_NOINIT_UNSPECIFIED
	#include "Dcm_MemMap.h"
	VAR(Dcm_RoutineControlStateType,DCM_VAR_NOINIT)Dcm_RoutineControlState[DCM_DSP_ROUTINE_MAX_NUM];
	#define DCM_STOP_SEC_VAR_NOINIT_UNSPECIFIED
	#include "Dcm_MemMap.h"
#endif

/****************************** Implement***********************************/
/*************************************************************************/
/*
 * Brief               <The Dsp layer response to the confirmation>
 * ServiceId           <None>
 * Sync/Async          <Synchronous>
 * Reentrancy          <Reentrant>
 * Param-Name[in]      <ProtocolCtrlId:The corresponding protocol control block ID number>
 * Param-Name[out]     <None>
 * Param-Name[in/out]  <None>
 * Return              <None>
 * PreCondition        <None>
 * CallByAPI           <APIName>
 */
/*************************************************************************/
/*************************************/
#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
FUNC(void,DCM_CODE)DspInternal_DcmConfirmation(uint8 ProtocolCtrlId)
{
#if((STD_ON == DCM_SECURITY_FUNC_ENABLED)&&((STD_ON == DCM_UDS_SERVICE0X27_ENABLED)))
    P2CONST(Dcm_DspSecurityRowType,AUTOMATIC,DCM_CONST)pSecurityRow;
    uint8   SecCfgIndex;
#endif
    uint8   MsgCtrlId;
    uint8   RxChannelCtrlId;
    uint8   TxChannelCtrlId;
    Std_ReturnType ret;
    uint8 iloop;
    Dcm_OpStatusType OpStatus = DCM_INITIAL;
    uint16  Offset;

    MsgCtrlId = Dcm_ProtocolCtrl[ProtocolCtrlId].MsgCtrlIndex;
    RxChannelCtrlId = Dcm_MsgCtrl[MsgCtrlId].Dcm_RxCtrlChannelIndex;
    TxChannelCtrlId = Dcm_MsgCtrl[MsgCtrlId].Dcm_TxCtrlChannelIndex;
    /************************************************/
    /*NRC = 0x78 respond to the confirmation process*/
    if(DCM_E_RESPONSE_PENDING==(Dcm_MsgCtrl[MsgCtrlId].NRC))
    {
        /*Nrc=0x78,response to confirmation*/
        /************************************/
        if(ReProgramingRequest == TRUE)
        {
            /*clear ReProgramingRequest Flag*/
            ReProgramingRequest = FALSE;
            for (iloop = 0;iloop < Dcm_DspCfg.pDcm_DspSession->DcmDspSessionRow_Num;iloop++)
            {
                if ((Dcm_SesCtrl.Dcm_NewSes == Dcm_DspCfg.pDcm_DspSession->pDcmDspSessionRow[iloop].DcmDspSessionLevel)
                     && (Dcm_DslCfg.pDcmDslProtocol->pDcmDslProtocolRow[ProtocolCtrlId].DcmSendRespPendOnTransToBoot == TRUE))
                {
                    /*[SWS_Dcm_00535] */
                    if ((Dcm_DspCfg.pDcm_DspSession->pDcmDspSessionRow[iloop].DcmDspSessionForBoot == DCM_OEM_BOOT)
                            || (Dcm_DspCfg.pDcm_DspSession->pDcmDspSessionRow[iloop].DcmDspSessionForBoot == DCM_SYS_BOOT))
                    {
                        ret = Dcm_SetProgConditions(OpStatus,&ProgConditions);
                        if (ret == E_OK)
                        {
                            /* By this mode switch the DCM informs the BswM to jump to the bootloader.*/
                            (void)SchM_Switch_DcmEcuReset(RTE_MODE_DcmEcuReset_EXECUTE);/*[SWS_Dcm_01163]*/
                        }
                        else if (ret == DCM_E_PENDING)
                        {
                            Dcm_MsgCtrl[MsgCtrlId].Dcm_OpStatus = DCM_PENDING;
                        }
                        else
                        {
                            /*idle*/
                        }
                    }
                    else if ((Dcm_DspCfg.pDcm_DspSession->pDcmDspSessionRow[iloop].DcmDspSessionForBoot == DCM_OEM_BOOT_RESPAPP)
                            || (Dcm_DspCfg.pDcm_DspSession->pDcmDspSessionRow[iloop].DcmDspSessionForBoot == DCM_SYS_BOOT_RESPAPP))
                    {
                        /*[SWS_Dcm_01177]*/
                        Offset = (Dcm_DslCfg.pDcmChannelCfg)[TxChannelCtrlId].offset;
                        Dcm_Channel[Offset] = 0x50;
                        Dcm_Channel[Offset + 1u] = Dcm_SesCtrl.Dcm_NewSes;
                        Dcm_Channel[Offset + 2u] = (uint8)(Dcm_DspCfg.pDcm_DspSession->pDcmDspSessionRow[iloop-1u].DcmDspSessionP2ServerMax >>8u);
                        Dcm_Channel[Offset + 3u] = (uint8)(Dcm_DspCfg.pDcm_DspSession->pDcmDspSessionRow[iloop-1u].DcmDspSessionP2ServerMax);
                        Dcm_Channel[Offset + 4u] = (uint8)((Dcm_DspCfg.pDcm_DspSession->pDcmDspSessionRow[iloop-1u].DcmDspSessionP2StarServerMax) >>8u);
                        Dcm_Channel[Offset + 5u] = (uint8)(Dcm_DspCfg.pDcm_DspSession->pDcmDspSessionRow[iloop-1u].DcmDspSessionP2StarServerMax);
                        Dcm_MsgCtrl[MsgCtrlId].MsgContext.ResMaxDataLen = 6u;
                        Dcm_MsgCtrl[MsgCtrlId].MsgContext.ResDataLen    = 6u;
                        Dcm_MsgCtrl[MsgCtrlId].MsgContext.pResData = &Dcm_Channel[Offset];
                        SchM_Exit_Dcm(Dcm_Channel);
                        SchM_Exit_Dcm(Dcm_MsgCtrl);

                        Dcm_MsgCtrl[Dcm_ProtocolCtrl[ProtocolCtrlId].MsgCtrlIndex].RspStyle = DCM_POS_RSP;
                        Dcm_MsgCtrl[Dcm_ProtocolCtrl[ProtocolCtrlId].MsgCtrlIndex].Dcm_MsgState = DCM_MSG_PROCESSED;
                        Dcm_ChannelCtrl[TxChannelCtrlId].Dcm_BufferCunrentPosition = 0;
                        if (Dcm_MsgCtrl[MsgCtrlId].MsgContext.MsgAddInfo.SuppressPosResponse == TRUE)
                        {
                        	Dcm_MsgCtrl[Dcm_ProtocolCtrl[ProtocolCtrlId].MsgCtrlIndex].RspStyle = DCM_POS_RSP_SUPPRESS;
                        }
                        Dcm_MsgCtrl[MsgCtrlId].NRC = 0xFFu;
                        DsdInternal_ProcessingDone(ProtocolCtrlId);
                        ret = Dcm_SetProgConditions(OpStatus,&ProgConditions);/*[SWS_Dcm_01179]*/
                        if (ret == E_OK)
                        {
                            return;
                        }
                        else if (ret == DCM_E_PENDING)
                        {
                            Dcm_MsgCtrl[MsgCtrlId].Dcm_OpStatus = DCM_PENDING;
                        }
                        else
                        {}
                    }
                    else
                    {}
                }
            }
        }
        SchM_Enter_Dcm(Dcm_MsgCtrl);
        Dcm_MsgCtrl[MsgCtrlId].NRC = 0xFFu;
        Dcm_MsgCtrl[MsgCtrlId].SendFlag = FALSE;
        Dcm_MsgCtrl[MsgCtrlId].RspStyle = DCM_POS_RSP;
        Dcm_MsgCtrl[MsgCtrlId].Dcm_MsgState = DCM_MSG_RECEIVED;
        Dcm_ChannelCtrl[RxChannelCtrlId].Dcm_ChannelRxState = DCM_CH_OCCUPIED;
        Dcm_ChannelCtrl[TxChannelCtrlId].Dcm_ChannelTxState = DCM_CH_OCCUPIED;
        Dcm_ChannelCtrl[TxChannelCtrlId].Dcm_BufferCunrentPosition = 0;
        Dcm_ChannelCtrl[TxChannelCtrlId].Dcm_BufferErasePosition = 0;
        /*restart P2*Timer*/
        Dcm_MsgCtrl[MsgCtrlId].Dcm_P2Ctrl.PendingNum++;
        Dcm_MsgCtrl[MsgCtrlId].Dcm_P2Ctrl.Dcm_P2CurTimer 	 = Frt_ReadOutMS();
        Dcm_MsgCtrl[MsgCtrlId].Dcm_P2Ctrl.Dcm_P2ExpiredTimer = Dcm_ProtocolCtrl[ProtocolCtrlId].P2StarServerMax -
        		Dsl_ProtocolRowCfg[ProtocolCtrlId].DcmTimStrP2StarServerAdjust;
        Dcm_MsgCtrl[MsgCtrlId].Dcm_P2Ctrl.Dcm_P2State    	 = DCM_P2TIMER_ON;
        SchM_Exit_Dcm(Dcm_MsgCtrl);        
        return;
    }
    /************************************************/
#if((STD_ON == DCM_SECURITY_FUNC_ENABLED)&&((STD_ON == DCM_UDS_SERVICE0X27_ENABLED)))
    /*securityAccess service*/
    if ((0x27u == Dcm_MsgCtrl[MsgCtrlId].SID)
           && (DCM_NEG_RSP == Dcm_MsgCtrl[MsgCtrlId].RspStyle)
           && (DCM_E_GENERALREJECT == Dcm_MsgCtrl[MsgCtrlId].NRC))
    {
          /*confirmation to reject SecurityAccess service*/
          DslInternal_SetSecurityAccessStatus(DCM_SERVICE_IDLE);
    }
    if ((0x27u == Dcm_MsgCtrl[MsgCtrlId].SID)
           && ( (DCM_POS_RSP == Dcm_MsgCtrl[MsgCtrlId].RspStyle)
        	    || (DCM_POS_RSP_SUPPRESS == Dcm_MsgCtrl[MsgCtrlId].RspStyle) )
           && (DCM_SERVICE_KEY == Dcm_SecCtrl.Dcm_SecServiceState))
    {
        /*Compare key success*/
    	/****@req DCM-FUNR-179[DCM325]****/
        DslInternal_SetSecurityLevel(Dcm_SecCtrl.Dcm_NewSec);
        DslInternal_SetSecurityAccessStatus(DCM_SERVICE_IDLE);
		/***********************************/
        ret = DslInternal_GetSecurityCfgBySecLevel(Dcm_SecCtrl.Dcm_ActiveSec, &SecCfgIndex);
        if (E_OK == ret)
        {
            SchM_Enter_Dcm(Dcm_SecCtrl);
            Dcm_SecCtrl.Dcm_SubfunctionForSeed = 0u;
            Dcm_SecCtrl.Dcm_RunDlyCtrl.Dcm_SecTimerState[SecCfgIndex] = DCM_SECTIMER_OFF;
            SchM_Exit_Dcm(Dcm_SecCtrl);
            Dcm_SecCtrl.Dcm_FalseAcessCount[SecCfgIndex]    = 0u;
            pSecurityRow = &(Dcm_DspCfg.pDcm_DspSecurity->pDcm_DspSecurityRow[SecCfgIndex]);
            if (pSecurityRow != NULL_PTR)
            {
                /*SWS_Dcm_01157*/
                if ((TRUE == pSecurityRow->DcmDspSecurityAttemptCounterEnabled)
                   &&(((USE_ASYNCH_FNC == pSecurityRow->DcmDspSecurityUsePort)
                           || (USE_ASYNCH_CLIENT_SERVER == pSecurityRow->DcmDspSecurityUsePort))))
                {
                    if (pSecurityRow->Dcm_SetSecurityAttemptCounterFnc != NULL_PTR)
                    {
                        /*SWS_Dcm_01154*/
                        (void)pSecurityRow->Dcm_SetSecurityAttemptCounterFnc(Dcm_SecCtrl.Dcm_OpStatus, Dcm_SecCtrl.Dcm_FalseAcessCount[SecCfgIndex]);
                    }
                }
            }
        }
    }
#endif

    /************************************************/
#if((STD_ON == DCM_SESSION_FUNC_ENABLED)&&((STD_ON == DCM_UDS_SERVICE0X10_ENABLED)))
    /*session control sevice confirmation*/
    if((   (DCM_POS_RSP == Dcm_MsgCtrl[MsgCtrlId].RspStyle)
				|| (DCM_POS_RSP_SUPPRESS == Dcm_MsgCtrl[MsgCtrlId].RspStyle))
        && (0x10u == Dcm_MsgCtrl[MsgCtrlId].SID))
    {
        for (iloop = 0;iloop < Dcm_DspCfg.pDcm_DspSession->DcmDspSessionRow_Num;iloop++)
        {
            if (Dcm_SesCtrl.Dcm_NewSes == Dcm_DspCfg.pDcm_DspSession->pDcmDspSessionRow[iloop].DcmDspSessionLevel)
            {
                if ((Dcm_DspCfg.pDcm_DspSession->pDcmDspSessionRow[iloop].DcmDspSessionForBoot == DCM_SYS_BOOT_RESPAPP)
                    || (Dcm_DspCfg.pDcm_DspSession->pDcmDspSessionRow[iloop].DcmDspSessionForBoot == DCM_OEM_BOOT_RESPAPP))
                {
                    ret = Dcm_SetProgConditions(OpStatus,&ProgConditions);/*[SWS_Dcm_01179]*/
                    if (ret == E_OK)
                    {
                        /* By this mode switch the DCM informs the BswM to jump to the bootloader.*/
                        (void)SchM_Switch_DcmEcuReset(RTE_MODE_DcmEcuReset_EXECUTE);/*[SWS_Dcm_01180]*/
                    }
                    else if (ret == DCM_E_PENDING)
                    {
                        Dcm_MsgCtrl[MsgCtrlId].Dcm_OpStatus = DCM_PENDING;
                    }
                    else
                    {
                        /*idle*/
                    }
                }
            }
        }
    	/*Uds 0x10 service*/
    	/****@req DCM-FUNR-109[DCM311]****/
        DslInternal_SesRefresh(Dcm_SesCtrl.Dcm_NewSes);
    }
#endif

    /**********************************************/
#if (STD_ON == DCM_DSP_ECU_RESET_FUNC_ENABLED)
    if(  ((DCM_POS_RSP == Dcm_MsgCtrl[MsgCtrlId].RspStyle)
    		||(DCM_POS_RSP_SUPPRESS == Dcm_MsgCtrl[MsgCtrlId].RspStyle) )
      && (0x11u == Dcm_MsgCtrl[MsgCtrlId].SID))
    {
        if(TRUE == gAppl_UpdataOK_ResponseFlag)
        {
        	gAppl_UpdataOK_ResponseFlag = FALSE;  /*clear app updata flag*/
        	DslInternal_SesRefresh(DCM_DEFAULT_SESSION);
        }
        else
        {
        	/*confirm to EcuReset service,call Mcu_PerformReset trigger reset*/
    		/****@req DCM-FUNR-113[DCM374]****/

        	switch(Dcm_MsgCtrl[MsgCtrlId].Subfunction)
        	{
        	case RTE_MODE_DcmEcuReset_HARD:
        		(void)SchM_Switch_DcmEcuReset(RTE_MODE_DcmEcuReset_HARD);
        		break;
        	case RTE_MODE_DcmEcuReset_SOFT:
        		(void)SchM_Switch_DcmEcuReset(RTE_MODE_DcmEcuReset_SOFT);
        		break;
            default:
                break;
        	}

        	(void)SchM_Switch_DcmEcuReset(RTE_MODE_DcmEcuReset_EXECUTE);

        }
    }
#endif

#if(STD_ON == DCM_PAGEDBUFFER_ENABLED)
    if (Dcm_PageBufferData.TotalSize != 0UL)
    {
        DslInternal_InitPageBuffer();
    }
#endif
    /***********************************************
     For the realization of the various sub-function,
     the function code needs to be added here.
     ***********************************************/
    (void)DslInternal_ResetResource(ProtocolCtrlId);
    return;
}
#define  DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"

/****************************************************************************/
#if ((STD_ON == DCM_DSP_ROUTINE_FUNC_ENABLED) && (DCM_DSP_ROUTINE_MAX_NUM > 0))
#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
FUNC(void,DCM_CODE)Dsp_InitRoutineStates(void)
{
    uint8 index;
    for (index = 0; index < DCM_DSP_ROUTINE_MAX_NUM; index++)
    {
        Dcm_RoutineControlState[index] = DCM_DSP_ROUTINE_INIT;
    }
}
#define  DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif

#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
FUNC(Std_ReturnType, DCM_CODE)Dcm_UdsSubServicesCheck( uint8 ProtocolCtrlId)
{
	uint16  SidTabCfgIndex;
	uint16  SidTabServiceCfgIndex;
	uint8   MsgCtrlIndexx;
	uint16  SubServieCfgIndex;
	uint8   Sid;
	Std_ReturnType  ret;

	MsgCtrlIndexx = Dcm_ProtocolCtrl[ProtocolCtrlId].MsgCtrlIndex;
	Sid = Dcm_MsgCtrl[MsgCtrlIndexx].SID;

    ret = DsdInternal_SearchSidTabServiceIndex(Sid,
                                               ProtocolCtrlId,
                                               &SidTabCfgIndex,
                                               &SidTabServiceCfgIndex);

    if(E_NOT_OK == ret)
    {
       return  E_NOT_OK;
    }
    else
    {
    	ret = DsdInternal_SearchSidTabSubServiceIndex(ProtocolCtrlId,
													SidTabCfgIndex,
													SidTabServiceCfgIndex,
													&SubServieCfgIndex);
    	if (E_NOT_OK == ret)
    	{
    		return ret;
    	}
    }

    return E_OK;
}
#define  DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"

#if(STD_ON == DCM_PAGEDBUFFER_ENABLED)
#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
FUNC(void,DCM_CODE)DspInternal_DcmUpdatePage(uint8 ProtocolCtrlId)
{
	Dcm_PageBufferData.PageTxOK = TRUE;
	Dcm_PageBufferData.ThisPageTxSize = 0;
	Dcm_PageBufferData.CurTimer  = Frt_ReadOutMS();
	Dcm_PageBufferData.TimerStart = TRUE;
	Dcm_PageBufferData.ExpiredTimer = DCM_PAGEBUFFER_TIMEOUTVALUE;
    /*Start P2Timer Timer*/
    /*SWS_Dcm_01142*/
    (void)DslInternal_P2ServerStart(ProtocolCtrlId);
}
#define  DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif
